﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Data.Common;
using System.Reflection;
using System.Data.OleDb;
using System.Data.OracleClient;
using Dominio;

namespace Persistencia
{
    public class TurmaDAO
    {
        protected int _count = 0;
        protected SqlConnection conn = null;
        protected void closeConexao()
        {
            GerenciadorConexao.closeConexao(conn);
            conn = null;
        }
        protected void abrirConexao()
        {
            if (conn.State != ConnectionState.Open)
                conn.Open();
        }
        public int selectCountAll()
        {
            return _count;
        }
        #region métodos auxiliares
        private String getNomeTabela() {
            return "Turma";
        }
        private String getSelect()
        {
            return "select id, serie, nome, ano, turno, qtdalunos from " + this.getNomeTabela();
        }

        protected DbParameter novoParametro(String nome, DbType tipo, Object valor)
        {
            SqlParameter par = new SqlParameter();
            par.ParameterName = nome;
            if (tipo !=null)
                par.DbType = tipo;
            if (valor != null)
                par.Value = valor;
            return par;

        }
        private TurmaVO getEntidade(DbDataReader dr)
        {
            TurmaVO turma = new TurmaVO();

            try
            {
                turma.id = (int)dr["id"];
                turma.Nome = (string)dr["nome"].ToString().Trim();
                turma.Serie = (string)dr["serie"].ToString().Trim();
                turma.Ano = (int)Convert.ToInt32(dr["ano"]);
                turma.Turno = (string)dr["turno"].ToString().Trim();
                turma.Qtdalunos = (int)Convert.ToInt32(dr["qtdalunos"]);
                
            }
            catch (Exception)
            {
            }
            return turma;
        }
        #endregion
        #region métodos acessadores
        public IList<TurmaVO> list(int  ano, string serie, string turno)
        {
            return this.recuperarTurmas(ano, serie, turno);
        }
        /// <summary>
        /// Exibe todos os objetos cadastrados.
        /// </summary>
        /// <returns>Retorna a lista de objetos da classe T.</returns>
        
        private List<TurmaVO> recuperarTurmas(int ano, string serie, string turno)
        {
            List<TurmaVO> turma = new List<TurmaVO>();

            conn = GerenciadorConexao.getConexao();

            SqlCommand command = new SqlCommand(this.getSelect() + " where ano LIKE @parAno and serie LIKE '%' + @parSerie + '%' and turno LIKE '%' + @parTurno + '%' ORDER BY ano desc, serie, turno;", conn);

            abrirConexao();

            string _ano = ano.ToString();
            string _serie = serie;
            string _turno = turno;

            if (_ano == "0") _ano = "%";
            if (_serie == null) _serie = "";
            if (_turno == null) _turno = "";
            
            try
            {                
                command.Parameters.Add(this.novoParametro("@parAno", DbType.String, _ano));
                command.Parameters.Add(this.novoParametro("@parSerie", DbType.String, _serie));
                command.Parameters.Add(this.novoParametro("@parTurno", DbType.String, _turno));
                DbDataReader dr = command.ExecuteReader();
                try
                {
                    if (dr.HasRows)
                    {
                        while (dr.Read())
                        {
                            turma.Add(this.getEntidade(dr));
                        }
                    }
                }
                finally { dr.Close(); }
            }
            finally { closeConexao(); }

            return turma;
        }
        public TurmaVO findByPrimaryKey(int id)
        {
            //Activator.CreateInstance(
            TurmaVO vo = new TurmaVO();
            conn = GerenciadorConexao.getConexao();
            
            SqlCommand command = new SqlCommand(this.getSelect() + " where id = @parID", conn);

            abrirConexao();
            try
            {
                command.Parameters.Add(this.novoParametro("parID", DbType.Int32,id));
                DbDataReader dr = command.ExecuteReader();
                try
                {
                    if (dr.HasRows)
                    {
                        dr.Read();
                        vo = this.getEntidade(dr);
                    }
                }
                finally { dr.Close(); }
            }
            finally { closeConexao(); }

            return vo;
        }

        public int GET_COUNT_alunos(int id_turma)
        {
            conn = GerenciadorConexao.getConexao();

            SqlCommand command = new SqlCommand("Select count(Aluno.nome) as qtdalunos from Aluno where ID_Turma = @id_turma", conn);

            abrirConexao();
            int qtdaluno = 0;

            try
            {
                command.Parameters.Add(this.novoParametro("id_turma", DbType.Int32, id_turma));
                
                DbDataReader dr = command.ExecuteReader();
                try
                {
                    if (dr.HasRows)
                    {
                        while (dr.Read())
                        {
                            qtdaluno = (int)Convert.ToInt32(dr["qtdalunos"]);
                        }
                    }
                }
                finally { dr.Close(); }
            }
            finally { closeConexao(); }

            return qtdaluno;
        }

        #endregion
        #region métodos modificadores
        public int inserir(TurmaVO vo)
        {
            int retorno = 0;

            conn = GerenciadorConexao.getConexao();

            SqlCommand command = new SqlCommand();
            command.CommandText =  "INSERT INTO " + this.getNomeTabela() + " (nome, serie, ano, turno) VALUES (@nome, @serie, @ano, @turno)";
            command.Connection = conn;

            command.Parameters.Add(this.novoParametro("nome", DbType.String,vo.Nome));
            command.Parameters.Add(this.novoParametro("serie", DbType.String,vo.Serie));
            command.Parameters.Add(this.novoParametro("ano", DbType.String, vo.Ano));
            command.Parameters.Add(this.novoParametro("turno", DbType.String, vo.Turno));
            

            try
            {
                abrirConexao();
                
                retorno = command.ExecuteNonQuery();
                if (retorno > 0)
                    vo.id = GerenciadorConexao.getId(this.getNomeTabela());
                return retorno;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
            finally
            {
                closeConexao();
            }
        }
        public virtual int alterar(TurmaVO vo)
        {
            int retorno = 0;

            conn = GerenciadorConexao.getConexao();

            SqlCommand command = new SqlCommand();
            command.CommandText = "UPDATE " + this.getNomeTabela() + " set nome = @nome, serie = @serie, ano = @ano, turno = @turno where id = @id";
            command.Connection = conn;

            command.Parameters.Add(this.novoParametro("nome", DbType.String, vo.Nome));
            command.Parameters.Add(this.novoParametro("@id", DbType.Int32, vo.id));
            command.Parameters.Add(this.novoParametro("serie", DbType.String, vo.Serie));
            command.Parameters.Add(this.novoParametro("ano", DbType.String, vo.Ano));
            command.Parameters.Add(this.novoParametro("turno", DbType.String, vo.Turno));

            try
            {
                abrirConexao();
                retorno = command.ExecuteNonQuery();
                return retorno;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
            finally
            {
                closeConexao();
            }
        }
        public virtual int atualizarQTDAlunos()
        {
            conn = GerenciadorConexao.getConexao();
            int retorno = 0;
            SqlCommand command = new SqlCommand("Select ID from "+this.getNomeTabela(), conn);
            abrirConexao();
            List<int> ids = new List<int>();

            try
            {                
                DbDataReader dr = command.ExecuteReader();
                try
                {
                    if (dr.HasRows)
                    {
                        while (dr.Read())
                        {
                            ids.Add(this.getID(dr));
                        }
                    }
                }
                finally { dr.Close(); }
            }
            finally { closeConexao(); }

            //Alterar QTDalunos de todas as tabelas
            for (int i = 0; i < ids.Count; i++)
            {
                retorno = alterarQTDAlunos(ids[i]);
            }
            return retorno;
        }
        private int getID(DbDataReader dr)
        {
            int id = 0;

            try
            {
                id = (int)dr["id"];
            }
            catch (Exception)
            {
            }
            return id;
        }
        public virtual int alterarQTDAlunos(int id_turma)
        {
            int retorno = 0;
            int qtdalunos = 0;
            
            qtdalunos = GET_COUNT_alunos(id_turma);
            SqlCommand command = new SqlCommand();
            
            command.CommandText = "UPDATE " + this.getNomeTabela() + " set qtdalunos = @qtdalunos where ID = @id";
            command.Parameters.Add(this.novoParametro("qtdalunos", DbType.Int32, qtdalunos));
            command.Parameters.Add(this.novoParametro("@id", DbType.Int32, id_turma));
            conn = GerenciadorConexao.getConexao();
            command.Connection = conn;

            try
            {
                abrirConexao();
                retorno = command.ExecuteNonQuery();
                return retorno;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
            finally
            {
                closeConexao();
            }
        }
        #endregion
    }

    }

